/*
 * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package io.iec.edp.caf.tenancy.core.utils;

import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
import io.iec.edp.caf.commons.dataaccess.JDBCConnectionInfo;
import io.iec.edp.caf.commons.dataaccess.SimpleDbConfigData;
import io.iec.edp.caf.commons.utils.SpringBeanUtils;
import io.iec.edp.caf.data.source.DbConfigDataConvertor;
import io.iec.edp.caf.tenancy.api.entity.DbConnectionInfo;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;

import javax.sql.DataSource;

/**
 * HelperTools
 *
 * @author Hey Law
 * @create 2019年8月21日11:55:41$
 */
@Slf4j
public class HelperTools {

    /**
     * ToDataSource
     *
     * @param dbConnectionInfo 连接信息
     * @return
    */
    public static DataSource toDataSource(DbConnectionInfo dbConnectionInfo) {
        SimpleDbConfigData dataSource = new SimpleDbConfigData();
        dataSource.setId(dbConnectionInfo.getId());
        dataSource.setDbType(dbConnectionInfo.getDbType());
        dataSource.setConnectionString(dbConnectionInfo.getConnectionString());

//        GSPDbConfigData configData = DbConfigDataConvertor.convert(dataSource);
        JDBCConnectionInfo info = DbConfigDataConvertor.convert(dataSource);

        return createDataSource(dbConnectionInfo.getId(), info);
//        return null;
    }

    /**
     *
     * @param info
     * @return
     */
    public static DataSource createDataSource(String id, JDBCConnectionInfo info){
        HikariConfig wholeHikariConfig= SpringBeanUtils.getBean(HikariConfig.class);
        HikariConfig hikariConfig;
        String driverName = info.getDriverClassName();
        String jdbcUrl = info.getJdbcUrl();
        if(driverName.equals(wholeHikariConfig.getDriverClassName()) &&
                jdbcUrl.equals(wholeHikariConfig.getJdbcUrl()) &&
                info.getUserName().equals(wholeHikariConfig.getUsername())&&
                info.getPassword().equals(wholeHikariConfig.getPassword())) {
            hikariConfig = wholeHikariConfig;
        }else {
            hikariConfig = new HikariConfig();
            hikariConfig.setPoolName(String.format("tenancy-%s",id));
            hikariConfig.setDriverClassName(info.getDriverClassName());
            hikariConfig.setJdbcUrl(jdbcUrl);
            hikariConfig.setUsername(info.getUserName());
            hikariConfig.setPassword(info.getPassword());
            if(info.getMaxPoolSize()!=null && info.getMaxPoolSize()>0)
                hikariConfig.setMaximumPoolSize(info.getMaxPoolSize());
            else
                hikariConfig.setMaximumPoolSize(wholeHikariConfig.getMaximumPoolSize());
            hikariConfig.setMinimumIdle(1);
            hikariConfig.setConnectionTestQuery(wholeHikariConfig.getConnectionTestQuery());
//        hikariConfig.setPoolName("springHikariCP");
//        hikariConfig.addDataSourceProperty("dataSource.cachePrepStmts", "true");
//        hikariConfig.addDataSourceProperty("dataSource.prepStmtCacheSize", "250");
//        hikariConfig.addDataSourceProperty("dataSource.prepStmtCacheSqlLimit", "2048");
//        hikariConfig.addDataSourceProperty("dataSource.useServerPrepStmts", "true");
        }
        log.debug("tenentIdentity: "+id);
        log.debug("hikariConfig.setDriverClassName:"+wholeHikariConfig.getDriverClassName());
        log.debug("hikariConfig.setJdbcUrl:"+jdbcUrl);
        log.debug("hikariConfig.setUsername:"+info.getUserName());
        log.debug("hikariConfig.setPassword:"+info.getPassword());
        return new HikariDataSource(hikariConfig);
    }
}

@Data
class ConnectionInfo{
    private String database;
    private String server;
    private String port;
    private String userId;
    private String password;
    private Integer maxPoolSize;
}
